package cn.chendd.shiro.custom;

import cn.chendd.shiro.custom.examples.SysUser;
import cn.chendd.shiro.custom.examples.SysUserDao;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.realm.text.IniRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 自定义登录认证实现，示例使用不再继承IniRealm，省去一个ini的配置文件
 *
 * @author chendd
 */
public class LoginEncryptionRealm extends IniRealm {

    Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public String getName() {
        return "chendd-login-encryption-realm";
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        return null;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        UsernamePasswordToken userToken = (UsernamePasswordToken) token;
        String userName = userToken.getUsername();
        SysUserDao dao = new SysUserDao();
        SysUser sysUser = dao.getUserByUserName(userName);
        if (sysUser == null) {
            throw new AuthenticationException("用户名或密码不匹配！");//实际上是用户不存在
        }
        //加密密码，使用用户名加盐并迭代2次
        String password = this.encodePassword(new String(userToken.getPassword()), userName);
        logger.debug("输入密码为：{}，数据库密码为：{}", password, sysUser.getPassword());
        if (!sysUser.getPassword().equals(password)) {
            throw new AuthenticationException("用户名或密码不匹配！");
        }
        //构造授权认证对象返回
        SimpleAuthenticationInfo auth = new SimpleAuthenticationInfo(userName,
                userToken.getPassword(), ByteSource.Util.bytes(userName), this.getName());
        return auth;
    }

    /**
     * 得到加盐迭代两次后的密文
     */
    private String encodePassword(Object source, String salt) {
        Md5Hash md5 = new Md5Hash(source, salt, 2);
        return md5.toHex();
    }

}
